home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 2 / Mac Magazin and MacEasy Magazine CD - Issue 02.iso / Sharewarebibliothek / Applikationen / Alpha.5.81 folder / Help / XTCLs < prev   
Text File  |  1994-03-08  |  8KB  |  226 lines

  1.  
  2.     XTCLs (CopyRight 1992 by Tim Endres, modified by Pete Keleher)
  3.  
  4. The tcl external command interface is similar to the HyperCard external 
  5. command interface. Your code is a stand alone module that exists as a 
  6. resource in the common XTCL File or in a file by itself.
  7.  
  8. The advantage of having your XTCL in a separate file is the ability to have 
  9. access to your own set of resources that are always carried around with the 
  10. XTCL. The disadvantage is the cost of opening and close the XTCL's file 
  11. every time it is executed. 
  12.  
  13. When Alpha is asked to execute the external command, it loads the resource 
  14. from the (1) application resource fork, (2) the XTCL File resource fork, or (3) 
  15. the resource fork of the optional file parameter. The resource is locked 
  16. down in memory, and called as a C function. The external command's C 
  17. code should begin as:
  18.  
  19. void
  20. XTCLEntry(argc, argv, xpb)
  21. long            argc;
  22. char            **argv;
  23. XTCLParmBlk        *xpb;
  24.  
  25. The parameters are similar to what you would expect any C type program 
  26. to take, except for the xpb parameter block. This parameter block is your 
  27. link back into Alpha. Here is the structure:
  28.  
  29. typedef struct {
  30.  ->    long    version;
  31. <->    long    result;
  32. <->    Handle    resultH;
  33.  ->    short    cmdRefNum;
  34.  ->    Handle    cmdHandle;
  35.  ->    Tcl_Interp    *interp;
  36.  ->    int    (*eval)();
  37.  ->    ModalFilterProcPtr    modalproc;
  38.  -    long    reserved;
  39.     } XTCLParmBlk, *XTCLPBPtr;
  40.  
  41. The version field is passed in to indicate to the command what level of 
  42. functionality the tcl callback function supports, as well as indicate the 
  43. version of the parameter block data structure. The current version number 
  44. of defined by XTCL_CB_VERSION in the header file XTCL.h and is currently 
  45. 0x00010001.
  46.  
  47. The result field is returned by the external command and is to be one of 
  48. the predefined constants in XTCL.h. The resultH field contains a handle 
  49. that is allocated by Alpha, with a length of zero, and passed to the external 
  50. command to contain the results of the command. The command will resize 
  51. the handle to hold its result, and copy the results into the handle's memory 
  52. before returning. The external command should never dispose of the 
  53. handle passed in resultH.
  54.  
  55. The cmdRefNum field is the file system reference number of the file 
  56. containing the XTCL command. Remember, this reference number may be 
  57. the application's reference number or the number of the XTCL File, if the 
  58. command was found in either of these locations. The external command 
  59. must never close this file.
  60.  
  61. The cmdHandle field is the handle to the code resource that contains the 
  62. external command itself. It will be locked. Do not unlock, move, modify, or 
  63. otherwise mutilate this memory!!!! Consider the handle and data READ 
  64. ONLY.
  65.  
  66. The interp field is a tcl interpreter pointer to the interpreter that called the 
  67. external command. 
  68.  
  69. The eval field is a C procedure pointer to the callback routine to evaluate a 
  70. tcl statement. It is equivalent to using the eval tcl command. The callback is 
  71. used as follows:
  72.  
  73.    result = (* xpb->eval)(xpb, sHandle, rHandle, stdoutHandle);
  74.  
  75. Where:
  76. 'xpb' is the parameter block pointer passed to the external command.
  77. 'sHandle' is a handle containing a null terminated string to be evaluated by the tcl 
  78.   interpreter.
  79. 'rHandle' is a handle for the result of the command. It may be zero length, but if it is 
  80.   not the results will be placed after the data already in the handle (as determined by 
  81.   GetHandleSize). The result will not be null terminated, thus, GetHandleSize must 
  82.   be used to determine the length of the result. This field may be NULL.
  83. 'stdoutHandle' is a handle for the standard output of the command. This is the 
  84.   output generated by the print command and error reporting. It may be zero length, 
  85.   but if it is not the results will be placed after the data already in the handle (as 
  86.   determined by GetHandleSize). The results will not be null terminated, thus, 
  87.   GetHandleSize must be used to determine the length of the result. This 
  88.   field may be NULL.
  89.  
  90. The modalproc field is a procedure pointer to use in the 
  91. ModalFilterProcPointer field of ModalDialog and the like. 
  92.  
  93. The reserved field is reserved. 
  94.  
  95.  
  96. Two example XTCLs created in Think C 5.04 are in the 'xtcls' directory. 
  97. The first merely returns a result based on its arguments. The second uses 
  98. the 'eval' field of the XTCLParmBlk to have Alpha evaluate a script which 
  99. adds a menu of all available sounds to Alpha's menubar. Selecting one of 
  100. the menu items calls back into the XTCL and plays the sound. A compiled 
  101. version of this XTCL is loaded into the Alpha binary. Use it by going to 
  102. the home directory in the Tcl shell (cd <cr>), and then typing "xtclcmd 
  103. sounds init".
  104.  
  105. When creating XTCLs in ThinkC:
  106. 1) Global data is fine, but static initialization of pointers to the 
  107.    addresses of global data is not.
  108. 2) Except for the MacTraps library, all the libraries use global data. In 
  109.    order to use them in your code resource, you must make a copy that 
  110.    uses register a4 instead of a5 to reference global data. Make a copy 
  111.    of the library you need, and change the project type to 'Code 
  112.    Resource'. 
  113. 3) Remember that 'argc' is passed as a long.
  114.  
  115.  
  116. An external command in MPW C should look like:
  117.  
  118. #include "xtcl.h"
  119.  
  120. void
  121. XTCLEntry(argc, argv, xpb)
  122. int            argc;
  123. char        **argv;
  124. XTCLParmBlk    *xpb;
  125. {
  126. char    *ptr, state;
  127. int        i, length, slen;
  128.  
  129.     xpb->result = TCL_OK;
  130.     
  131.     length = GetHandleSize(xpb->resultH);
  132.     
  133.     for (i=1; i < argc; i++)
  134.         slen += strlen(argv[i]) + 1;
  135.  
  136.     SetHandleSize(xpb->resultH, slen+1);
  137.     
  138.     state = HGetState(xpb->resultH);
  139.     HLock(xpb->resultH);
  140.     
  141.     for (ptr=*xpb->resultH, i=1; i < argc; i++) {
  142.         strcat(ptr, argv[i]);
  143.         strcat(ptr, " ");
  144.         ptr += strlen(ptr);
  145.         }
  146.  
  147.     HSetState(xpb->resultH, state);
  148.     }
  149.  
  150. And would be linked together with:
  151.  
  152. XTCL_echo ƒ                ∂
  153.         XTCL_echo.c.o
  154.     Echo '#' Linking XTCL_echo
  155.     Link -t "XTCL" -c "MPS "        ∂
  156.         -rt "XTCL=2020"        ∂
  157.         -sg "echo"            ∂
  158.         -m XTCLEntry            ∂
  159.         -o XTCL_echo            ∂
  160.         XTCL_echo.c.o            ∂
  161.         {CLibraries}StdCLib.o    ∂
  162.         {Libraries}Interface.o
  163.  
  164. NOTE: The -sg "echo" option in the Link command will determined the 
  165. name of the code resource that is produced, and thus the name of the 
  166. external command. The -rt "XTCL=2020" option in the Link command 
  167. determines the resource type of the code generated, and its resource id. 
  168. The resource type must be XTCL, and the resource ID should try to be 
  169. unique, but is not critical.
  170.  
  171. Also remember that stand alone C code must not use global variables, and 
  172. must use the -b option when calling the C compiler to use string constants.
  173.  
  174. Finally, the following code fragment is an example of an XTCL that simply 
  175. calls the eval callback routine with its first argument to be evaluated.
  176.  
  177. #include "xtcl.h"
  178.  
  179. void
  180. XTCLEntry(argc, argv, xpb)
  181. int        argc;
  182. char        **argv;
  183. XTCLParmBlk    *xpb;
  184.     {
  185.     long        length;
  186.     int        result;
  187.     Handle        rHandle, sHandle;
  188.     char        *script = argv[1];
  189.  
  190.     xpb->result = TCL_OK;
  191.     
  192.     length = strlen(script);
  193.     sHandle = NewHandle(length+1);
  194.     rHandle = NewHandle(0);
  195.     
  196.     if (sHandle != NULL && rHandle != NULL)
  197.         {
  198.         strcpy(*sHandle, script);
  199.         
  200.         result = (* xpb->eval)(xpb, sHandle, rHandle, NULL);
  201.         
  202.         length = GetHandleSize(rHandle);
  203.         SetHandleSize(xpb->resultH, length + 1);
  204.         if (MemError() == noErr) {
  205.             memcpy(*xpb->resultH, *rHandle, GetHandleSize(rHandle));
  206.             * (*xpb->resultH + length) = '\0';
  207.             }
  208.         else
  209.             result = TCL_ERROR;
  210.         
  211.         xpb->result = result;
  212.         }
  213.     
  214.     if (sHandle != NULL)
  215.         DisposHandle(sHandle);
  216.     if (rHandle != NULL)
  217.         DisposHandle(rHandle);
  218.     }
  219.  
  220.  
  221.  
  222. NOTE: Pascal programmers will need to link with the Pascal glue code to 
  223. work. The glue code provides a C entry that will call your Pascal routine for 
  224. the XTCL. It also provides glue to callback the interpreter for evaluation. 
  225. Please see the example sources and makefile for further details.
  226.